// Copyright 2018 The Feed Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.android.libraries.feed.basicstream.internal.viewholders;

import static com.google.android.libraries.feed.common.Validators.checkNotNull;

import android.content.Context;
import android.support.annotation.VisibleForTesting;
import android.support.v7.widget.RecyclerView.LayoutParams;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.MarginLayoutParams;
import android.widget.FrameLayout;
import com.google.android.libraries.feed.common.ui.LayoutUtils;
import com.google.android.libraries.feed.host.config.Configuration;
import com.google.android.libraries.feed.host.stream.CardConfiguration;
import com.google.android.libraries.feed.sharedstream.logging.LoggingListener;
import com.google.android.libraries.feed.sharedstream.logging.VisibilityMonitor;

/** {@link android.support.v7.widget.RecyclerView.ViewHolder} for the more button. */
public class ContinuationViewHolder extends FeedViewHolder {

  private final View actionButton;
  private final View spinner;
  private final VisibilityMonitor visibilityMonitor;
  private final CardConfiguration cardConfiguration;

  public ContinuationViewHolder(
      Configuration configuration,
      Context context,
      FrameLayout frameLayout,
      CardConfiguration cardConfiguration) {
    super(frameLayout);
    View containerView =
        LayoutInflater.from(context).inflate(R.layout.feed_more_button, frameLayout);
    actionButton = checkNotNull(frameLayout.findViewById(R.id.action_button));
    spinner = checkNotNull(frameLayout.findViewById(R.id.loading_spinner));
    visibilityMonitor = createVisibilityMonitor(containerView, configuration);
    this.cardConfiguration = cardConfiguration;
  }

  public void bind(
      OnClickListener onClickListener, LoggingListener loggingListener, boolean showSpinner) {
    ViewGroup.LayoutParams layoutParams = itemView.getLayoutParams();
    if (layoutParams == null) {
      layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
      itemView.setLayoutParams(layoutParams);
    } else if (!(layoutParams instanceof MarginLayoutParams)) {
      layoutParams = new LayoutParams(layoutParams);
      itemView.setLayoutParams(layoutParams);
    }
    LayoutUtils.setMarginsRelative(
        (MarginLayoutParams) layoutParams,
        cardConfiguration.getCardStartMargin(),
        0,
        cardConfiguration.getCardEndMargin(),
        cardConfiguration.getCardBottomMargin());

    actionButton.setOnClickListener(
        v -> {
          onClickListener.onClick(v);
          loggingListener.onContentClicked();
        });
    visibilityMonitor.setListener(loggingListener);
    setButtonSpinnerVisibility(showSpinner);
  }

  @Override
  public void unbind() {
    // Clear OnClickListener to null to allow for GC.
    actionButton.setOnClickListener(null);
    visibilityMonitor.setListener(null);

    // Set clickable to false as setting OnClickListener to null sets clickable to true.
    actionButton.setClickable(false);
  }

  public void setShowSpinner(boolean showSpinner) {
    setButtonSpinnerVisibility(/* showSpinner= */ showSpinner);
  }

  private void setButtonSpinnerVisibility(boolean showSpinner) {
    actionButton.setVisibility(showSpinner ? View.GONE : View.VISIBLE);
    spinner.setVisibility(showSpinner ? View.VISIBLE : View.GONE);
  }

  @VisibleForTesting
  VisibilityMonitor createVisibilityMonitor(
      /*@UnderInitialization*/ ContinuationViewHolder this, View view, Configuration configuration) {
    return new VisibilityMonitor(view, configuration);
  }
}
